#!/usr/bin/perl -w
# Capture deadlock message 
# @param $1 install home
# @param $2 delimiter
# @param $3 host
# @param $4 port
# @param $5 username
# @param $6 password
# @param $7 1:Display deadlock CONTENT 2:Dispaly deadlock occurrence in 300s 
# 2009-07-29 Davidli --intinal created
use strict;
use Time::Local;
my $INTERVAL = 300; ## seconds
my $SQL="show innodb status\\G";
my ($MYSQL_HOME,$DELIM,$HOST,$PORT,$USER,$PASS,$SWITCH) = @ARGV;
my $PARAM="";
$PARAM="$PARAM -h\"$HOST\"" if (defined($HOST) && $HOST ne "");
$PARAM="$PARAM -P\"$PORT\"" if (defined($PORT) && $PORT ne "");
$PARAM="$PARAM -u\"$USER\"" if (defined($USER) && $USER ne "");
$PARAM="$PARAM -p\"$PASS\"" if (defined($PASS) && $PASS ne "");
my $MYSQL="$MYSQL_HOME/bin/mysql";
my $MYSQLADMIN="$MYSQL_HOME/bin/mysqladmin";
if ($^O =~ m/MSWin32/) {
  $MYSQL =~ s/\//\\/g;
  $MYSQLADMIN =~ s/\//\\/g;
}
# Check if mysqld is alive
my $retmsg=`$MYSQLADMIN $PARAM ping 2>&1`;
chomp($retmsg);
if ( "$retmsg" ne "mysqld is alive" ) {
    print "em_error=Status${DELIM}Down\n";
    exit 1;
}
my $C=`$MYSQL -N -s $PARAM -e"$SQL"`;
chomp($C);
#print "$C";
my $rownum = 0;

############################################
#LATEST DETECTED DEADLOCK    #Header
#------------------------
#090723 11:10:53
#*** (1) TRANSACTION:
#.....
#*** WE ROLL BACK TRANSACTION (1) #Tailer
############################################
while($C =~ /(?:(\d{2})(\d{2})(\d{2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})\n(\*{3}\s+\(\d\).*?\*{3}\s+WE ROLL BACK TRANSACTION\s+\(\d\)))+/msg){
  my $year_yy        = $1;
  my $month_mm       = $2;
  my $day_dd         = $3;
  my $hour_hh24      = $4;
  my $minute_mi      = $5;
  my $second_ss      = $6;
  my @info           = split('\n',$7); ##store deadlock in line

  ##if two diginal number point to before 2000 or after 3000,it will cause logical error
  my $year_yyyy      = 2000 + $year_yy;

  ##timelocal($sec, $min, $hour, $day,$Month,$year); $month range is betwee 0 and 11,So $month_mm -1.
  my $deadlocktime   = timelocal($second_ss,$minute_mi,$hour_hh24,$day_dd,$month_mm-1,$year_yyyy); 

  my $checktime      = time;
  #print "$deadlocktime\n";
  #print "$checktime\n";
  my $diff           = ($checktime - $deadlocktime);
  my $INTERVAL       = defined ($INTERVAL) ? "$INTERVAL" : "300";
  $INTERVAL          = 300 if ( $INTERVAL =~ /^$|\s+/);
  #print "$INTERVAL\n"; 
  
  ## if DeadLock  has happened between interval, it would be captured
  if ( $diff <= $INTERVAL ) {
     $rownum ++;
     if ( $SWITCH == 1 ) {
        #inital block number
        my $block_number = 0;

        #display deadlock info in line
        foreach my $deadlock_info(@info) {
                $block_number ++;
                chomp($deadlock_info);
                print "em_result=$year_yyyy-$month_mm-$day_dd $hour_hh24:$minute_mi:${second_ss}|$rownum|$block_number|${deadlock_info}\n";
       }
    }
  }
}

if ( $SWITCH == 2 ) {
  my $deadlocknum = $rownum;
  print "em_result=$deadlocknum\n";
}
